package serveur.controller;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import serveur.model.entite.Joueur;

import commons.downloader.Downloader;
import commons.downloader.ServerDownloader;
/**
 * 
 * @author michael
 *
 */
public class ThreadJoueur extends Thread {
	Socket s;
	static List<Socket> bWriterListe = new ArrayList<Socket>();
	JoueurController controller = new JoueurController();
	BufferedReader fluxEntre;
	BufferedWriter fluxSortie;
	String bReaderTemp;
	String action,value;
	Downloader synchIm;
	Joueur joueur;
	Partie partie;
	
	public ThreadJoueur(Socket s){
		this.s = s;
		//this.synchIm = new ServerDownloader(Serveur.cheminDossier);
		ThreadJoueur.bWriterListe.add(s);
	}
	
	public void run() {
		while(true){
			try {
				fluxEntre = new BufferedReader(new InputStreamReader(s.getInputStream()));
				fluxSortie = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
				bReaderTemp = fluxEntre.readLine()+"\n";
			} catch (IOException e1) {
				try {
					s.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				e1.printStackTrace();
			}

			action = bReaderTemp.split(":")[0];
			System.out.println("action du serveur "+action);
			
			/**Identification ou inscription**/
			if(action.equals("inscription")){
				value = bReaderTemp.split(":")[1];
				//enregistre le joueur, si une erreur survien, envoi d'une erreur
				if((this.joueur = controller.save(value))==null){
					try {
						fluxSortie.write("ErreurInscription:\n");
						fluxSortie.flush();
					} catch (IOException e) {
						e.printStackTrace();
					}
					System.out.println("erreur inscription");
				}else{
					try {
						fluxSortie.write("InscriptionOk:\n");
						fluxSortie.flush();
					} catch (IOException e) {
						e.printStackTrace();
					}
					//synchronisation();
					System.out.println("inscription ok : "+joueur.getPseudo());
				}
			}else if (action.equals("connexion")){
				value = bReaderTemp.split(":")[1];
				if((this.joueur = controller.authentification(value))==null){
					try {
						fluxSortie.write("ErreurAuthentification:\n");
						fluxSortie.flush();						
						System.out.println("erreur d'authentification");
					} catch (IOException e) {
						e.printStackTrace();
					}
				}else{
					try {
						fluxSortie.write("AuthentificationOk:\n");
						fluxSortie.flush();
						//getPartiesEnCour(fluxSortie);	
						System.out.println("authentifier : "+joueur.getPseudo());
					} catch (IOException e) {
						e.printStackTrace();
					}
					//qynchronisation des images
					//synchronisation();
				}
			} 
			//retourne sur les partie en cour
			if(action.equals("getListePartie")){
				getPartiesEnCour(fluxSortie);
			}
			//debut de la partie
			if (action.equals("commencer")) {
				value = bReaderTemp.split(":")[1];
				value = value.substring(0, value.length()-1);
				System.out.println("new partie = "+value);
				this.partie = new Partie(value);
				this.partie.addJoueurPartie(joueur, s);
				try {
					System.out.println("serveur envoi flux Jouer:"+partie.getCurrentImage().getId()+"-"+partie.getCurrentImage().getReponse()+"\n");
					fluxSortie.write("Jouer:"+partie.getCurrentImage().getId()+"-"+partie.getCurrentImage().getReponse()+"\n");
					fluxSortie.flush();
					fluxSortie.write("PartieEnCours:"+value+","+joueur.getPseudo()+"\n");
					fluxSortie.flush();
					System.out.println("partie cr�e : "+value+" par "+joueur.getPseudo());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}else if (action.equals("rejoindre")) {
				//un joueur rejoind une partie
				try {
					value = bReaderTemp.split(":")[1];
					this.partie = Partie.getPartieIntoListe(value);
					this.partie.addJoueurPartie(joueur,s);
					System.out.println("joueur ajouter a la partie");
					fluxSortie.write("Jouer:"+partie.getCurrentImage().getId()+"-"+partie.getCurrentImage().getReponse()+"\n");
					fluxSortie.flush();
					System.out.println("serveur : "+joueur.getPseudo()+" a rejin la partie "+value);
				} catch (IOException e) {
					e.printStackTrace();
				}
			} 
			//un joueur a trouver la bonne reponse 
			if (action.equals("gagner")) {
				this.partie.gagner();	
				try {
					fluxSortie.write("Jouer:"+partie.getCurrentImage().getId()+"-"+partie.getCurrentImage().getReponse()+"\n");
					fluxSortie.flush();
					System.out.println("marqu� 1 point : "+joueur.getPseudo());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	//r�cup�re la liste des partis et les envois une/une au joueur
	private void getPartiesEnCour(BufferedWriter fluxSortie) {
		Map<String, Partie> mapCourrente = Partie.getListePartie();
		for(Map.Entry<String, Partie> enCour : mapCourrente.entrySet()){
			System.out.println("ListePartieEnCour:"+enCour.getKey()+"\n");
			try {
				
				fluxSortie.write("PartieEnCours:"+enCour.getKey()+"\n");
				fluxSortie.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	
	/**Synchronisation des images**/
	public void synchronisation(){
		//Envoi de la hashTable
		try {
			this.synchIm.download(s);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	//permet la diffusion d'un message a tout les joueurs
	static public void diffusion(String value) {
		for(Socket socket : bWriterListe) {
			try {

				BufferedWriter brSocket = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
				brSocket.write(value+"\n");
				brSocket.flush();
				System.out.println("envoi "+value+" au client");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}